//
// Created by wujehy on 2020/5/29.
//

#ifndef GEEJOAN_KEYVALUEDATATYPE_H
#define GEEJOAN_KEYVALUEDATATYPE_H


/**
 * @brief Key-Value 数据封装 用于 GeeJoan 服务端 缓存 数据 , 代替 Redis
 */

#include <functional>

namespace GeeJoan
{
    namespace DataBase
    {
        typedef std::function<void(void *userdata)> UserPortDeleteFunction;

        class KeyValueDataType
        {
        public:
            enum ValueType
            {
                UNDEFINED = 0, ///< 未定义
                INT32 = 1, ///< 数字
                INT64 = 2, ///< 数字
                FLOAT = 3, ///< 小数
                DOUBLE = 4,
                BOOL = 5,
                STRING = 6,
                USERPORT = 7, ///< 指针
            };

            KeyValueDataType()
            {
                dataType = UNDEFINED;
            }

            ValueType getDataType() const
            {
                return dataType;
            }

            bool getStatus() const
            {
                return status;
            }

            float getDec32() const
            {
                return dec32;
            }

            double getDec64() const
            {
                return dec64;
            }

            int getNumber32() const
            {
                return number32;
            }

            int64_t getNumber64() const
            {
                return number64;
            }

            const std::string &getStr() const
            {
                return str;
            }

            void *getPort() const
            {
                return port;
            }

            KeyValueDataType(bool status) : status( status ), dataType( BOOL )
            {}

            KeyValueDataType(int64_t number) : number64( number ), dataType( INT64 )
            {}

            KeyValueDataType(int number) : number32( number ), dataType( INT32 )
            {}

            KeyValueDataType(const std::string &instr) : str( instr ), dataType( STRING )
            {}

            KeyValueDataType(const char *instr) : str( instr ), dataType( STRING )
            {}

            KeyValueDataType(double dec) : dec64( dec ), dataType( DOUBLE )
            {}

            KeyValueDataType(float dec) : dec32( dec ), dataType( FLOAT )
            {}

            KeyValueDataType(void *port, const UserPortDeleteFunction &deleteFunction) : port( port ),
                                                                                         deleteFunction(
                                                                                                 deleteFunction ),
                                                                                         dataType( USERPORT )
            {

            }

            /**
             * @brief 返回字符串的值
             * @return
             */
            virtual std::string getValue(bool showType = false)
            {
                switch (dataType)
                {
                    case KeyValueDataType::DOUBLE:
                    {

                        return (showType ? "(double) " : "") + std::to_string( dec64 );
                    }
                    case KeyValueDataType::FLOAT:
                    {
                        return (showType ? "(float) " : "") + std::to_string( dec32 );
                        break;
                    }
                    case KeyValueDataType::STRING :
                    {
                        return (showType ? "(string) " : "") + str;
                    }


                    case KeyValueDataType::INT32 :
                    {
                        return (showType ? "(int32) " : "") + std::to_string( number32 );
                    }

                    case KeyValueDataType::INT64 :
                    {
                        return (showType ? "(int64) " : "") + std::to_string( number64 );
                    }


                    case KeyValueDataType::BOOL :
                    {
                        return (showType ? "(bool) " : "") + std::to_string( status );
                    }
                    case KeyValueDataType::USERPORT :
                    {
                        return (showType ? "(addr) " : "") + std::to_string((int64_t) port );
                    }
                }
            }


            virtual ~KeyValueDataType()
            {
//                std::cout << "delete KeyValueDataType " << std::endl;
                // 释放 特定内存
                if (port != nullptr && deleteFunction != nullptr)
                {
                    deleteFunction( port );
                }
                return;
            }

        private:
            bool status = false;
            float dec32 = 0;
            double dec64 = 0;
            int number32 = 0;
            int64_t number64 = 0;
            std::string str;
            ValueType dataType = UNDEFINED;

            // 特定类型
            void *port = nullptr;
            UserPortDeleteFunction deleteFunction = nullptr;
        };

    }
}

#endif //GEEJOAN_KEYVALUEDATATYPE_H

